package generadores;


import model.Laberinto;
import model.objetos.*;
import model.posicion.Posicion;
import model.common.Constantes;
import model.fantasmas.*;

import java.util.*;
import view.VistaFantasma;
import ar.uba.fi.algo3.titiritero.Dibujable;

/*******************************************************************************
* aca habria que poner el generador de laberintos, voy a cear un par de metodos para probarlo
*******************************************************************************/
public class Generador {
	
	private int limiteX;
	private int limiteY;
	private Objetos[][] grilla;
	private Laberinto elLaberinto;
	private Posicion pPacman;
	private Posicion pBlinky;
	private Posicion pInky;
	private Posicion pClyde;
	private Posicion pPinky;
	private List<Fantasma> fantasmas;
	private int puntosLaberinto;
	private int nivel=0;
	
	public Generador(Laberinto elLaberinto,int nivel){
		

		this.puntosLaberinto=0;
		this.elLaberinto= elLaberinto;
		this.nivel=nivel;
		this.setearNivel(this.nivel);
	}
	
	
	public void avanzarNivel() {
		

		this.nivel+=1;
		int velocidad= Constantes.VELOCIDAD-10+(nivel*2);//reinicia los fantasmas con otra velocidad
		if(velocidad>=Constantes.VELOCIDAD)velocidad=Constantes.VELOCIDAD-1;//para que los fantasmas no sean mas rapidos que el pacman
		Iterator<Fantasma> iterator = this.fantasmas.iterator();
		while(iterator.hasNext()){
			Fantasma fantasmita = iterator.next();
			fantasmita.reiniciar();
			fantasmita.setVelocidad(velocidad);
		}
		
		this.reiniciarLaberinto();
		
	}

	private void reiniciarLaberinto() {

		for(Objetos[] vectorObjetos : this.grilla){
			for(Objetos objeto : vectorObjetos){
				objeto.cambiarEstado(true);
			}
		}
		
		
	}

	private void setearNivel(int nivel) {

		switch(nivel){
		case -2: {
			this.grilla=this.generarPuntosComunes();
			this.limiteX=4;
			this.limiteY=4;
			this.pPacman= new Posicion(0,1);
			this.pBlinky = new Posicion(0,3);
			this.pPinky = new Posicion(3,0);
			this.pInky = new Posicion(3,3);
			this.pClyde = new Posicion(2,2);
			this.generarFantasmas(1);
			break;
		}
		case -1:{
			this.grilla=this.generarParedes();
			this.limiteX=4;
			this.limiteY=4;
			this.pPacman= new Posicion(0,0);
			this.pBlinky = new Posicion(0,3);
			this.pPinky = new Posicion(0,2);
			this.pInky = new Posicion(3,0);
			this.pClyde = new Posicion(2,0);
			this.generarFantasmas(1);
			break;
		}
		case 0:{
			this.grilla=this.generarCruz();
			this.limiteX=5;
			this.limiteY=5;
			this.pPacman= new Posicion(0,2);
			this.pBlinky = new Posicion(2,0);
			this.pPinky = new Posicion(2,3);
			this.pInky = new Posicion(3,2);
			this.pClyde = new Posicion(2,2);
			this.generarFantasmas(1);
			break;
		}
		case 1:{
			this.grilla=this.generarNivelUno();
			this.limiteX=21;
			this.limiteY=19;
			this.pPacman= new Posicion(10,11);
			this.pBlinky = new Posicion(8,9);
			this.pPinky = new Posicion(9,9);
			this.pInky = new Posicion(11,9);
			this.pClyde = new Posicion(12,9);
			this.generarFantasmas(1);
			break;
		}
		case 2:{
			this.grilla=this.generarNivelUno();
			this.limiteX=21;
			this.limiteY=19;
			this.pPacman= new Posicion(10,11);
			this.pBlinky = new Posicion(8,9);
			this.pPinky = new Posicion(9,9);
			this.pInky = new Posicion(11,9);
			this.pClyde = new Posicion(12,9);
			this.generarFantasmas(2);
			break;
		}
		}
		
	}

	private Objetos[][] generarPuntosComunes(){
		
		this.grilla=new Objetos[4][4];
		for (int i=0; i<4; i++){
			for(int j=0; j<4; j++){
				this.puntosLaberinto+=1;
				grilla[i][j]= new PuntoComun(new Posicion(i,j), this.elLaberinto);
			}
		}
		return grilla;
	}
	
	private Objetos[][] generarParedes(){
		
		this.grilla=new Objetos[4][4];
		for (int i=0; i<4; i++){
			for(int j=0; j<4; j++){
				if(i==0 || j==0){
					this.puntosLaberinto+=1;
					grilla[i][j]= new PuntoComun(new Posicion(i,j), this.elLaberinto);
				}else{
					grilla[i][j]= new Pared(new Posicion(i,j), this.elLaberinto);
				}
			}
		}
		return grilla;
	}

	private Objetos[][] generarCruz() {
		
		this.grilla=new Objetos[5][5];
		for(int i=0;i<5;i++){
			for(int j=0;j<5;j++){
				if(i==2||j==2){
					grilla[i][j]= new PuntoComun(new Posicion(i,j), this.elLaberinto);
					this.puntosLaberinto+=1;
				}else{
					grilla[i][j]= new Pared(new Posicion(i,j), this.elLaberinto);
				}
			}
		}
		return grilla;
	}
	
	private Objetos[][] generarNivelUno(){//genera un nivel mas grande con las celdas transportador
		
		this.grilla=new Objetos[21][19];
		for(int i=0;i<21;i++){
			for(int j=0;j<19;j++){
					grilla[i][j]= new Pared(new Posicion(i,j), this.elLaberinto);
			}
		}
		for(int i=1;i<20;i++){
			for(int j=1;j<18;j++){
				if((i==1||j==1)||(i==19||j==17)){
					grilla[i][j]= new PuntoComun(new Posicion(i,j), this.elLaberinto);
					this.puntosLaberinto+=1;
				}
			}
		}
		for(int i=3;i<18;i++){
			for(int j=3;j<16;j++){
				if((i==3||j==3)||(i==17||j==15)){
					grilla[i][j]= new PuntoComun(new Posicion(i,j), this.elLaberinto);
					this.puntosLaberinto+=1;
				}
			}
		}
		for(int i=5;i<16;i++){
			for(int j=5;j<14;j++){
				if((i==5||j==5)||(i==15||j==13)){
					this.puntosLaberinto+=1;
					grilla[i][j]= new PuntoComun(new Posicion(i,j), this.elLaberinto);
				}
			}
		}
		for(int i=6;i<15;i++){
			for(int j=7;j<12;j++){
				if((i==6||j==7)||(i==14||j==11)){
					grilla[i][j]= new PuntoComun(new Posicion(i,j), this.elLaberinto);
					this.puntosLaberinto+=1;
				}
			}
		}
		for(int i=8;i<13;i++){
			grilla[i][9]= new Vacio(new Posicion(i,9), this.elLaberinto);
			//estos casilleros estan dentro del lugar donde nacen los fantasmas 
		}
		
		grilla[2][9]= new PuntoComun(new Posicion(2,9), this.elLaberinto);this.puntosLaberinto+=1;
		grilla[18][9]= new PuntoComun(new Posicion(18,9), this.elLaberinto);this.puntosLaberinto+=1;
		grilla[10][2]= new PuntoComun(new Posicion(10,2), this.elLaberinto);this.puntosLaberinto+=1;
		grilla[10][16]= new PuntoComun(new Posicion(10,16), this.elLaberinto);this.puntosLaberinto+=1;
		grilla[10][8]= new Vacio(new Posicion(10,8), this.elLaberinto);
		grilla[5][4]= new PuntoComun(new Posicion(5,4), this.elLaberinto);this.puntosLaberinto+=1;
		grilla[15][4]= new PuntoComun(new Posicion(15,4), this.elLaberinto);this.puntosLaberinto+=1;
		grilla[5][14]= new PuntoComun(new Posicion(5,14), this.elLaberinto);this.puntosLaberinto+=1;
		grilla[15][14]= new PuntoComun(new Posicion(15,14), this.elLaberinto);this.puntosLaberinto+=1;
		grilla[4][9]= new PuntoComun(new Posicion(4,9), this.elLaberinto);this.puntosLaberinto+=1;
		grilla[16][9]= new PuntoComun(new Posicion(16,9), this.elLaberinto);this.puntosLaberinto+=1;
		
		grilla[5][8]= new Pared(new Posicion(5,8), this.elLaberinto);this.puntosLaberinto-=1;
		grilla[5][10]= new Pared(new Posicion(5,10), this.elLaberinto);this.puntosLaberinto-=1;
		grilla[15][8]= new Pared(new Posicion(15,8), this.elLaberinto);this.puntosLaberinto-=1;
		grilla[15][10]= new Pared(new Posicion(15,10), this.elLaberinto);this.puntosLaberinto-=1;
		
		grilla[0][9]= new Transportador(new Posicion(0,9), new Posicion(20,9), elLaberinto);
		grilla[20][9]= new Transportador(new Posicion(20,9), new Posicion(0,9), elLaberinto);
		
		grilla[1][1] = new PuntoDePoder(new Posicion(1,1),this.elLaberinto);
		grilla[1][17] = new PuntoDePoder(new Posicion(1,17),this.elLaberinto);
		grilla[19][1] = new PuntoDePoder(new Posicion(19,1),this.elLaberinto);
		grilla[19][17] = new PuntoDePoder(new Posicion(19,17),this.elLaberinto);
		return grilla;
	}
	
	//le agregue la velocidad a los fantasmas
	private List<Fantasma> generarFantasmas(int nivel){
		
		int velocidad= Constantes.VELOCIDAD-10+(nivel*2);
		fantasmas = new ArrayList<Fantasma>();
		Fantasma fantasmaActual;
		
		fantasmaActual = new Blinky(pBlinky,elLaberinto, velocidad);
		fantasmas.add(fantasmaActual);
		
		fantasmaActual = new Clyde(pClyde,elLaberinto, velocidad);
		fantasmas.add(fantasmaActual);
		
		fantasmaActual = new Inky(pInky,elLaberinto, velocidad);
		fantasmas.add(fantasmaActual);
		
		fantasmaActual = new Pinky(pPinky,elLaberinto, velocidad);
		fantasmas.add(fantasmaActual);
		
		return fantasmas; 
		//elLaberinto.generarFantasmas(fantasmas);
	}

	public int getLimiteX() {
		return limiteX;
	}

	public int getLimiteY() {
		return limiteY;
	}

	public Posicion getpPacman() {
		return pPacman;
	}

	public Objetos[][] getGrilla() {
		return grilla;
	}
	
	public List<Dibujable> getFantasmasDibujar(){
		
		List<Dibujable> dibujable = new ArrayList<Dibujable>();
		
		for(int i=0;i<this.fantasmas.size();i++){
			VistaFantasma fantasmaVista = new VistaFantasma(this.fantasmas.get(i));
			fantasmaVista.setPosicionable(this.fantasmas.get(i));
			dibujable.add(fantasmaVista);
		}
		return dibujable;
	}

	public List<Fantasma> getFantasmas() {		
		return this.fantasmas;
	}

	public int getPuntosLaberinto() {
		return puntosLaberinto;
	}
	
}
